﻿// CWndINJ.cpp: 实现文件
//

#include "pch.h"
#include "GameHacker.h"
#include "CWndINJ.h"
#include "afxdialogex.h"


#pragma comment(lib, "ImageHlp.lib")


// CWndINJ 对话框

IMPLEMENT_DYNAMIC(CWndINJ, CDialogEx)

CWndINJ::CWndINJ(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_PAGE_0, pParent)
	, B_DEBUG(FALSE)
	, B_PAUSE(FALSE)
	, B_INJECT(FALSE)
{

}

CWndINJ::~CWndINJ()
{
}

void CWndINJ::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_LIST1, m_ExeList);
	DDX_Check(pDX, IDC_CHECK3, B_DEBUG);
	DDX_Check(pDX, IDC_CHECK2, B_PAUSE);
	DDX_Check(pDX, IDC_CHECK1, B_INJECT);
}


BEGIN_MESSAGE_MAP(CWndINJ, CDialogEx)
	ON_BN_CLICKED(IDC_BUTTON1, &CWndINJ::OnBnClickedButton1)
	ON_NOTIFY(NM_DBLCLK, IDC_LIST1, &CWndINJ::OnNMDblclkList1)
	ON_COMMAND(ID_MENU_SET, &CWndINJ::OnMenuSet)
	ON_COMMAND(ID_MENU_DEL, &CWndINJ::OnMenuDel)
	ON_NOTIFY(NM_RCLICK, IDC_LIST1, &CWndINJ::OnNMRClickList1)
END_MESSAGE_MAP()


// CWndINJ 消息处理程序


BOOL CWndINJ::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	//设置listbox的样式
	long lStyle;
	lStyle = GetWindowLongPtr(m_ExeList.m_hWnd, GWL_STYLE);
	lStyle |= LVS_REPORT;
	SetWindowLongPtr(m_ExeList.m_hWnd, GWL_STYLE, lStyle);
	lStyle = m_ExeList.GetExtendedStyle();
	lStyle |= LVS_EX_FULLROWSELECT;//一次选中一整行
	lStyle |= LVS_EX_GRIDLINES;//设置显示格子线
	m_ExeList.SetExtendedStyle(lStyle);

	m_ExeList.InsertColumn(0, L"游戏名称", 0, 150);
	m_ExeList.InsertColumn(1, L"可执行文件", 0, 300);
	m_ExeList.InsertColumn(2, L"文件夹", 0, 250);
	m_ExeList.InsertColumn(3, L"命令行参数", 0, 100);
	m_ExeList.InsertColumn(4, L"注入模块", 0, 300);

	return TRUE;  // return TRUE unless you set the focus to a control
				  // 异常: OCX 属性页应返回 FALSE
}


void CWndINJ::OnBnClickedButton1()
{
	m_WndAddGame.Init(this);
	m_WndAddGame.DoModal();
}

void CWndINJ::Init(CString& _path)
{
	//配置文件路径
	m_pStrIniPath = _path + L"\\set\\";
	if (!PathIsDirectory(m_pStrIniPath))
		CreateDirectory(m_pStrIniPath, NULL); //创建set文件夹
	m_pStrIniPath += L"Games.ini";
	//加载游戏信息到窗口
	LoadGame();
}


void CWndINJ::AddGame(CString& GameName, CString& GameFile, CString& GamePath, CString& GameCmd, CString& GameMod)
{
	//写入到配置文件
	int count = GetPrivateProfileInt(L"main", L"count", 0, m_pStrIniPath);
	CString appName;
	appName.Format(L"count_%d", count);
	WritePrivateProfileString(appName, L"GameName", GameName, m_pStrIniPath);
	WritePrivateProfileString(appName, L"GameFile", GameFile, m_pStrIniPath);
	WritePrivateProfileString(appName, L"GamePath", GamePath, m_pStrIniPath);
	WritePrivateProfileString(appName, L"GameCmd", GameCmd, m_pStrIniPath);
	WritePrivateProfileString(appName, L"GameMod", GameMod, m_pStrIniPath);
	count++;
	CString _count;
	_count.Format(L"%d", count);
	WritePrivateProfileString(L"main", L"count", _count, m_pStrIniPath);

	//写入到游戏列表listbox
	int i = m_ExeList.GetItemCount();
	m_ExeList.InsertItem(i, GameName);
	m_ExeList.SetItemText(i, 1, GameFile);
	m_ExeList.SetItemText(i, 2, GamePath);
	m_ExeList.SetItemText(i, 3, GameCmd);
	m_ExeList.SetItemText(i, 4, GameMod);
}

void CWndINJ::SaveGame(CString& GameName, CString& GameFile, CString& GamePath, CString& GameCmd, CString& GameMod, int nIndex)
{
	//写入到配置文件
	CString appName;
	appName.Format(L"count_%d", nIndex);
	WritePrivateProfileString(appName, L"GameName", GameName, m_pStrIniPath);
	WritePrivateProfileString(appName, L"GameFile", GameFile, m_pStrIniPath);
	WritePrivateProfileString(appName, L"GamePath", GamePath, m_pStrIniPath);
	WritePrivateProfileString(appName, L"GameCmd", GameCmd, m_pStrIniPath);
	WritePrivateProfileString(appName, L"GameMod", GameMod, m_pStrIniPath);


	//写入到游戏列表listbox
	m_ExeList.SetItemText(nIndex, 0, GameName);
	m_ExeList.SetItemText(nIndex, 1, GameFile);
	m_ExeList.SetItemText(nIndex, 2, GamePath);
	m_ExeList.SetItemText(nIndex, 3, GameCmd);
	m_ExeList.SetItemText(nIndex, 4, GameMod);
}

void CWndINJ::LoadGame()
{
	int count = GetPrivateProfileInt(L"main", L"count", 0, m_pStrIniPath);
	if (count) {
		for (int i = 0; i < count; i++) {
			CString GameName, GameFile, GamePath, GameCmd, GameMod, appName;
			appName.Format(L"count_%d", i);
			TCHAR tRead[0x100];
			GetPrivateProfileString(appName, L"GameName", L"", tRead, 0x100, m_pStrIniPath);
			GameName.Format(L"%s", tRead);
			GetPrivateProfileString(appName, L"GameFile", L"", tRead, 0x100, m_pStrIniPath);
			GameFile.Format(L"%s", tRead);
			GetPrivateProfileString(appName, L"GamePath", L"", tRead, 0x100, m_pStrIniPath);
			GamePath.Format(L"%s", tRead);
			GetPrivateProfileString(appName, L"GameCmd", L"", tRead, 0x100, m_pStrIniPath);
			GameCmd.Format(L"%s", tRead);
			GetPrivateProfileString(appName, L"GameMod", L"", tRead, 0x100, m_pStrIniPath);
			GameMod.Format(L"%s", tRead);

			m_ExeList.InsertItem(i, GameName);
			m_ExeList.SetItemText(i, 1, GameFile);
			m_ExeList.SetItemText(i, 2, GamePath);
			m_ExeList.SetItemText(i, 3, GameCmd);
			m_ExeList.SetItemText(i, 4, GameMod);
		}
	}
}

void CWndINJ::SaveLstToIni()
{
	int count = m_ExeList.GetItemCount();
	for (int i = 0; i < count; i++) {
		CString GameName = m_ExeList.GetItemText(i, 0);
		CString GameFile = m_ExeList.GetItemText(i, 1);
		CString GamePath = m_ExeList.GetItemText(i, 2);
		CString GameCmd = m_ExeList.GetItemText(i, 3);
		CString GameMod = m_ExeList.GetItemText(i, 4);

		CString appName;
		appName.Format(L"count_%d", i);
		WritePrivateProfileString(appName, L"GameName", GameName, m_pStrIniPath);
		WritePrivateProfileString(appName, L"GameFile", GameFile, m_pStrIniPath);
		WritePrivateProfileString(appName, L"GamePath", GamePath, m_pStrIniPath);
		WritePrivateProfileString(appName, L"GameCmd", GameCmd, m_pStrIniPath);
		WritePrivateProfileString(appName, L"GameMod", GameMod, m_pStrIniPath);
	}

	int old_count = GetPrivateProfileInt(L"main", L"count", 0, m_pStrIniPath);
	while (old_count > count) {
		CString appName;
		appName.Format(L"count_%d", --old_count);
		WritePrivateProfileString(appName, NULL, NULL, m_pStrIniPath);
	}

	CString _count;
	_count.Format(L"%d", count);
	WritePrivateProfileString(L"main", L"count", _count, m_pStrIniPath);

}

void CWndINJ::OnNMDblclkList1(NMHDR* pNMHDR, LRESULT* pResult)
{
	LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
	*pResult = 0;

	int index = pNMItemActivate->iItem;
	if (index < 0) return;

	//读取游戏信息: 文件名,路径,命令行,需要注入的模块
	CString GameFile = m_ExeList.GetItemText(index, 1);
	CString GamePath = m_ExeList.GetItemText(index, 2);
	CString GameCmd = m_ExeList.GetItemText(index, 3);
	CString GameMod = m_ExeList.GetItemText(index, 4);

	UpdateData(true);

	BOOL bPause = B_PAUSE;
	if (B_INJECT && GameMod.GetLength() > 1) {
		bPause = true;
	}

	//启动游戏
	PROCESS_INFORMATION pi{};
	m_Inject.StartProcess(GameFile, GamePath, GameCmd.GetBuffer(), &pi, bPause);
	
	//启动od,调试游戏
	if (B_DEBUG) {
		PROCESS_INFORMATION od{};
		//此处可以修改为你自己的od路径
		CString OdFile(L"D:\\eDoYun\\工具\\OllyDbg\\Ollydbg.exe");
		CString OdPath(L"D:\\eDoYun\\工具\\OllyDbg\\");
		CString OdCmd;
		OdCmd.Format(L"-p %d", pi.dwProcessId);
		m_Inject.StartProcess(OdFile, OdPath, OdCmd.GetBuffer(), &od, false);
	}

	//注入模块
	if (B_INJECT && GameMod.GetLength() > 1) {
		//入口点注入
		m_Inject.CreateRemoteData(pi.hProcess, GameFile, GameMod);
	}

	if (B_PAUSE) {
		AfxMessageBox(L"按下确认,进程继续执行!");
	}
	//恢复挂起的游戏主线程
	ResumeThread(pi.hThread);
}


void CWndINJ::OnMenuSet()
{
	// TODO: 在此添加命令处理程序代码
	CString GameName = m_ExeList.GetItemText(m_nLstSeleted, 0);
	CString GameFile = m_ExeList.GetItemText(m_nLstSeleted, 1);
	CString GamePath = m_ExeList.GetItemText(m_nLstSeleted, 2);
	CString GameCmd = m_ExeList.GetItemText(m_nLstSeleted, 3);
	CString GameMod = m_ExeList.GetItemText(m_nLstSeleted, 4);
	
	m_WndAddGame.Init(this, false, m_nLstSeleted);
	m_WndAddGame.SetData(GameName, GameFile, GamePath, GameCmd, GameMod);
	m_WndAddGame.DoModal();
}



void CWndINJ::OnMenuDel()
{
	// TODO: 在此添加命令处理程序代码
	m_ExeList.DeleteItem(m_nLstSeleted);
	SaveLstToIni(); //重新保存游戏列表到配置文件
}


void CWndINJ::OnNMRClickList1(NMHDR* pNMHDR, LRESULT* pResult)
{
	LPNMITEMACTIVATE pActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
	// TODO: 在此添加控件通知处理程序代码
	*pResult = 0;

	if (pActivate->iItem != -1) {
		m_nLstSeleted = pActivate->iItem;
		DWORD dwPos = GetMessagePos();
		CPoint point(LOWORD(dwPos), HIWORD(dwPos));//记录鼠标位置
		CMenu menu;
		menu.LoadMenuW(IDR_MENU1);
		CMenu* popMenu = menu.GetSubMenu(0);
		popMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this); //弹出右键菜单
	}
}
